/* api */
import { batchAllotAuto, batchAllotPool, batchAllotTask, batchAutoDispatch } from '@src/api/TaskApi'
/* config */
import TaskConfig from '@model/config/TaskConfig'
/* components */
import TaskAllotSelect from '@src/modules/task/edit/components/TaskAllotSelect/TaskAllotSelect.vue'
/* entity */
import LoginUser from '@model/entity/LoginUser/LoginUser'
/* enum */
import AllotTypeEnum from '@model/enum/AllotTypeEnum'
import ComponentNameEnum from '@model/enum/ComponentNameEnum'
/* model */
import { 
  ALLOT_SYNERGY_MASSAGE, 
  BatchAllotExecutorSuccessMessage, 
  BatchAllotNotExecutorSuccessMessage, 
  BatchAllotPartSuccessMessage, 
  TASK_NO_EXECUTOR_MESSAGE 
} from '@src/model/const/Alert'
import { BatchAllotItemResult, getBatchAllotResult } from '@model/param/out/Task'
import { TaskBatchAllotModel } from '@model/param/in/Task'
/* service */
import { isAllotAuto, isAllotExecutor, isAllotTaskPool } from '@service/TaskService'
/* scss */
import '@src/modules/task/taskTypes/allot/components/BatchAllotDialog/BatchAllotDialog.scss'
/* util */
import Platform from '@src/platform'
import { strConcat as concat } from 'pub-bbx-utils'
import Log from '@src/util/log'
import { isOpenData, notification } from '@src/util/platform'
import { isEmpty } from '@src/util/type'
import i18n from '@src/locales'
/* vue */
import VC from '@model/VC'
import { Component, Prop, Ref } from 'vue-property-decorator'
import { CreateElement } from 'vue'

@Component({ 
  name: ComponentNameEnum.BatchAllotDialog,
  components: {
    [TaskAllotSelect.name]: TaskAllotSelect
  }
})
export default class BatchAllotDialog extends VC {
  
  @Ref() TaskAllotSelectComponent!: TaskAllotSelect
  
  @Prop() readonly taskIdList: string[] | undefined
  @Prop() readonly taskConfig: TaskConfig | undefined
  @Prop({ default: () => [AllotTypeEnum.Auto, AllotTypeEnum.Normal, AllotTypeEnum.Pool] }) 
  readonly typeOptions: string[] | undefined
  
  private allotType: AllotTypeEnum = AllotTypeEnum.Normal
  private executorUsers: LoginUser[] = []
  private loading: boolean = false
  private synergiesUsers: LoginUser[] = []
  private visibleDialog: boolean = false
  private allotTypeMap: object = {
    'pool': '派单到工单池',
    'normal': '派单到工单负责人',
    'auto': '自动分配',
    'waitDistribution': '保存至待分配列表',
  }
  
  get tasksCount(): number {
    return this.taskIdList?.length || 0
  }
  
  private buildParams() {
    //是否是自动分配
    const isCanAutoAllot = isAllotAuto(this.allotType);
    const synergiesIds = this.synergiesUsers.map(synergiesUser => synergiesUser.userId) || []
    const taskIdList = isCanAutoAllot ? (this.taskIdList || []) : concat(this.taskIdList || [])

    let params: TaskBatchAllotModel = {
      synergiesIds: isCanAutoAllot ? synergiesIds : concat(synergiesIds),
      ...(isCanAutoAllot ? { taskIdList } : { taskIds: taskIdList })
    }
    
    if (isAllotExecutor(this.allotType)) {
      params.executorId = this.executorUsers.length > 0 ? this.executorUsers?.[0].userId : ''
    }
    
    return params
  }
  
  private batchAllotNotExecutorSuccessMessageElement (
    succAllotList: BatchAllotItemResult[],
    synergyUsers: LoginUser[],
    exeInSynergyMessage: string
  ) {
    return (
      <ui-empty>
        <div>
          {i18n.t('task.tip.allotTaskTip2', {num: succAllotList.length})}，
          {i18n.t('task.synergies')}：
          { this.renderMessageSynergyUsers(synergyUsers) }
          
          <div>
            { exeInSynergyMessage }
          </div>
          
        </div>
      </ui-empty>
    )
  }
  
  private batchAllotExecutorSuccessMessageElement(
    succAllotList: BatchAllotItemResult[],
    synergyUsers: LoginUser[],
    executorUsers: LoginUser[],
    exeInSynergyMessage: string
  ) {
    return (
      <ui-empty>
        <div>
        {i18n.t('task.tip.allotTaskTip2', {num: succAllotList.length})}，{i18n.t('task.taskTypes.allot.taskExecutor')}：
          
          {isOpenData ? (
            <open-data type="userName" openid={executorUsers?.[0].staffId} key={executorUsers?.[0].userId}></open-data>
          ): (
            <span>{executorUsers?.[0].displayName}</span>
          )}
          
          {i18n.t('task.synergies')}：
          { this.renderMessageSynergyUsers(synergyUsers) }
          
          <div>
            { exeInSynergyMessage }
          </div>
          
        </div>
      </ui-empty>
    )
  }
  
  private cancel() {
    this.visibleDialog = false
  }
  
  /* 更改派单类型 */
  private changeAllotType(value: AllotTypeEnum) {
    this.allotType = value
  }
  
  /* 更改协同人 */
  private changeSynergies(value: LoginUser[]) {
    this.synergiesUsers = value
  }

  /* 更改负责人 */
  private changeExecutors(value: LoginUser[]) {
    this.executorUsers = value
  }
  
  private endLoading() {
    this.loading = false
  }
  
  /**
  * @description 获取属性列表
  * @return {Record<string, any>} 属性列表
  */  
  private getBaseModelAttributes(): Record<string, any> {
    return {
      class: ComponentNameEnum.BatchAllotDialog,
      style: 'z-index: 3000',
      props: {
        width: '700px',
        title: i18n.t('task.taskTypes.allot.batchAllot'),
        show: this.visibleDialog,
        appendToBody: true
      },
      on: {
        'update:show': (value: boolean) => {
          this.visibleDialog = value
        }
      }
    }
  }
  
  /**
  * @description 获取属性列表
  * @return {Record<string, any>} 属性列表
  */  
  private getTaskAllotSelectAttributes(): Record<string, any> {
    return {
      on: {
        'update:type': (value: AllotTypeEnum) => {
          this.changeAllotType(value)
        },
        'update:synergies': (value: LoginUser[]) => {
          this.changeSynergies(value)
        },
        'update:executors': (value: LoginUser[]) => {
          this.changeExecutors(value)
        }
      }
    }
  }
  
  private getBatchAllotAction() {
    if (isAllotTaskPool(this.allotType)) return batchAllotPool
    if (isAllotAuto(this.allotType)) return batchAutoDispatch
    
    return batchAllotTask
  }
  
  private openDialog(): void {
    this.visibleDialog = true
  }
  
  public outsideOpenDialog() {
    this.openDialog()
  }
  
  private refreshTab(): void {
    // Platform.refreshTab(getFromId())
    this.$emit('refresh') // 刷新列表
    this.visibleDialog = false
  }
  
  private startLoading() {
    this.loading = true
  }
  
  private async submit(): Promise<void> {
    // @ts-ignore
    this.$track.clickStat(this.$track.formatParams('BATCH_ALLOT_DONE', this.allotTypeMap[this.allotType]));
    // 效验分配至负责人 负责人必选
    if (this.executorUsers.length != 1 && this.allotType === AllotTypeEnum.Normal) {
      return Platform.alert(TASK_NO_EXECUTOR_MESSAGE)
    }
    
    this.startLoading()
    
    try {
      const allotAction = this.getBatchAllotAction()
      const params = this.buildParams()
      const result = await allotAction(params)

      if(isAllotAuto(this.allotType)) {
        result.data = result.result
      }
      
      // 全部派单成功
      if (result.status == 0) {
        this.submitWithFullSuccess(result)
      }
      // 部分派单成功
      else if (result.status == 1) {
        this.submitWithPartSuccess(result)
      }
      else {
        this.submitWithFail(result)
      }
      
      this.endLoading()
      
    } catch (error) {
      this.endLoading()
      Log.error(error, this.submit.name)
    }
  }
  
  /**
   * @description 批量指派提交全部成功
   * @param {getBatchAllotResult} result 提交结果
   * @return {void}
   */  
  private submitWithFullSuccess(result: getBatchAllotResult) {
    // 转派成功的列表
    const successAllotList: BatchAllotItemResult[] = result?.data?.succ || []
    // 是否将客户负责人带入协同人
    const exeInSynOfTaskOrEvent: boolean = successAllotList.some(batchAllotItemResult => batchAllotItemResult.exeInSynOfTaskOrEvent)
    // 带入协同人提示信息
    const exeInSynergyMessage: string = exeInSynOfTaskOrEvent ? '' : ALLOT_SYNERGY_MASSAGE
    
    // 派单到工单池或自动分配的提示
    if (isOpenData) {
      this.submitWithFullSuccessWithWX(successAllotList, exeInSynergyMessage)
    } else {
      this.submitWithFullSuccessWithNotWX(successAllotList, exeInSynergyMessage)
    }
    
    this.refreshTab()
  }
  
  private submitWithFullSuccessWithNotWX(successAllotList: BatchAllotItemResult[], exeInSynergyMessage: string) {
    // 派单到工单池或自动分配的提示
    if(isAllotTaskPool(this.allotType) || isAllotAuto(this.allotType)) {
      Platform.alert(
        BatchAllotNotExecutorSuccessMessage(
          successAllotList, 
          this.synergiesUsers, 
          exeInSynergyMessage
        )
      )
    } else {
      Platform.alert(
        BatchAllotExecutorSuccessMessage(
          successAllotList, 
          this.synergiesUsers, 
          this.executorUsers, 
          exeInSynergyMessage
        )
      )
    }
  }
  
  private submitWithFullSuccessWithWX(successAllotList: BatchAllotItemResult[], exeInSynergyMessage: string) {
    if(isAllotTaskPool(this.allotType) || isAllotAuto(this.allotType)) {
      notification({
        title: '',
        message: this.batchAllotNotExecutorSuccessMessageElement(successAllotList, this.synergiesUsers, exeInSynergyMessage)
      })
    } else {
      notification({
        title: '',
        message: this.batchAllotExecutorSuccessMessageElement(successAllotList, this.synergiesUsers, this.executorUsers, exeInSynergyMessage)
      })
    }
  }
  
  /**
   * @description 批量指派提交部分成功
   * @param {getBatchAllotResult} result 提交结果
   * @return {void}
   */
  private submitWithPartSuccess(result: getBatchAllotResult): void {
    Platform.alert(BatchAllotPartSuccessMessage(result))
    this.refreshTab()
  }
  
  /**
   * @description 批量提交失败
   * @param {getBatchAllotResult} result 提交结果
   * @return {void}
   */
  private submitWithFail(result: getBatchAllotResult): void {
    Platform.alert(result.message)
  }
  
  private renderMessageSynergyUsers(synergyUsers: LoginUser[]) {
    if (isEmpty(synergyUsers)) return i18n.t('task.taskTypes.allot.null')
    if (isOpenData) {
      return (
        synergyUsers.map(synergyUser => {
          return <open-data type="userName" openid={synergyUser.staffId} key={synergyUser.userId}></open-data>
        })
      )
    }
    
    return concat(synergyUsers.map(synergyUser => synergyUser.displayName || ''))
  }
  
  render(h: CreateElement) {
    const baseModelAttrs = this.getBaseModelAttributes()
    const taskAllotSelectAttrs = this.getTaskAllotSelectAttributes()
    
    return (
      <base-modal {...baseModelAttrs}>
        <div class="dialog-body">
          <div class="dialog-body-content">
            {i18n.t('task.tip.allotTaskTip3', {num: this.tasksCount})}
            <task-allot-select 
              ref='TaskAllotSelectComponent'
              typeOptions={this.typeOptions}
              taskConfig={this.taskConfig}
              {...taskAllotSelectAttrs}
            >
            </task-allot-select>
          </div>
        </div>
        <div class="dialog-footer" slot="footer">
          <el-button disabled={this.loading} onClick={() => this.cancel()}>
            {i18n.t('common.base.cancel')}
          </el-button>
          <el-button type="primary" disabled={this.loading} onClick={() => this.submit()}>
            {i18n.t('common.base.confirm')}
          </el-button>
        </div>
      </base-modal>
    )
  }
}
